// src/pages/test/useStateTest/index.tsx - useState Hook 详解页面
import React, { useState } from 'react';
import { Card, Button, Space, Typography, Divider } from 'antd';

const { Title, Paragraph } = Typography;

// 模拟一个耗时的计算函数
const expensiveCalculation = (num: number): number => {
  console.log('执行耗时计算...');
  // 模拟耗时操作
  let result = 0;
  for (let i = 0; i < 1000000; i++) {
    result += num;
  }
  return result;
};

const UseStateTestPage: React.FC = () => {
  // useState 是 React 中最基础也是最重要的 Hook 之一
  // 它允许我们在函数组件中添加和管理状态
  
  // 基础用法：计数器示例
  // useState 返回一个数组：[当前状态值, 更新状态的函数]
  // 初始值为 0
  const [count, setCount] = useState<number>(0);
  
  // 字符串状态示例
  const [name, setName] = useState<string>('React 学习者');
  
  // 对象状态示例
  const [user, setUser] = useState({
    age: 25,
    email: 'example@react.com'
  });
  
  // 数组状态示例
  const [todos, setTodos] = useState<string[]>(['学习 useState', '实践 Hook']);
  
  // 复杂状态示例：用户列表
  const [users, setUsers] = useState([
    { id: 1, name: '张三', isActive: true },
    { id: 2, name: '李四', isActive: false }
  ]);
  
  // 函数初始值示例
  // 使用函数初始值可以避免在每次渲染时都执行耗时的计算
  const [expensiveValue, setExpensiveValue] = useState<number>(() => {
    // 这个函数只会在组件首次渲染时执行一次
    return expensiveCalculation(10);
  });

  return (
    <Card title="useState Hook 详解" style={{ minHeight: '100%' }}>
      <Typography>
        <Title level={2}>useState Hook 简介</Title>
        <Paragraph>
          useState 是 React Hooks 中最基础的 Hook，它允许我们在函数组件中添加状态。
          在类组件时代，只有类组件才能拥有状态，而 useState 的出现让函数组件也具备了这个能力。
        </Paragraph>
        
        <Title level={3}>基础语法</Title>
        <Paragraph>
          <pre>
            {`const [state, setState] = useState(initialState);`}
          </pre>
        </Paragraph>
        <Paragraph>
          <ul>
            <li><code>state</code> - 当前状态值</li>
            <li><code>setState</code> - 更新状态的函数</li>
            <li><code>initialState</code> - 初始状态值</li>
          </ul>
        </Paragraph>
      </Typography>
      
      <Divider />
      
      {/* 计数器示例 */}
      <Title level={4}>1. 基础计数器示例</Title>
      <Space direction="vertical" style={{ width: '100%' }}>
        <Paragraph>
          当前计数: <strong>{count}</strong>
        </Paragraph>
        <Space>
          {/* 增加计数 */}
          <Button onClick={() => setCount(count + 1)}>
            增加 (+1)
          </Button>
          
          {/* 减少计数 */}
          <Button onClick={() => setCount(count - 1)}>
            减少 (-1)
          </Button>
          
          {/* 重置计数 */}
          <Button onClick={() => setCount(0)}>
            重置 (0)
          </Button>
          
          {/* 使用函数式更新 */}
          <Button onClick={() => setCount(prevCount => prevCount + 1)}>
            函数式增加 (+1)
          </Button>
        </Space>
        
        <Paragraph>
          <Typography.Text type="secondary">
            注意：当我们点击按钮时，setCount 函数会更新 count 状态，并触发组件重新渲染。
            函数式更新 (prevCount ={'>'} prevCount + 1) 在需要基于前一个状态计算新状态时特别有用。
          </Typography.Text>
        </Paragraph>
      </Space>
      
      <Divider />
      
      {/* 字符串状态示例 */}
      <Title level={4}>2. 字符串状态示例</Title>
      <Space direction="vertical" style={{ width: '100%' }}>
        <Paragraph>
          欢迎你，<strong>{name}</strong>！
        </Paragraph>
        <Space>
          <Button onClick={() => setName('React 初学者')}>
            设为"React 初学者"
          </Button>
          <Button onClick={() => setName('React 高级用户')}>
            设为"React 高级用户"
          </Button>
          <Button onClick={() => setName('React 专家')}>
            设为"React 专家"
          </Button>
        </Space>
      </Space>
      
      <Divider />
      
      {/* 对象状态示例 */}
      <Title level={4}>3. 对象状态示例</Title>
      <Space direction="vertical" style={{ width: '100%' }}>
        <Paragraph>
          用户信息：
          <br />
          年龄: <strong>{user.age}</strong>
          <br />
          邮箱: <strong>{user.email}</strong>
        </Paragraph>
        <Space>
          <Button onClick={() => setUser({...user, age: user.age + 1})}>
            增加年龄 (+1)
          </Button>
          <Button onClick={() => setUser({...user, age: user.age - 1})}>
            减少年龄 (-1)
          </Button>
          <Button onClick={() => setUser({...user, email: 'newemail@react.com'})}>
            更改邮箱
          </Button>
        </Space>
        <Paragraph>
          <Typography.Text type="secondary">
            注意：更新对象状态时，需要使用展开运算符(...)来保留其他属性，
            因为 useState 不会自动合并对象属性。
          </Typography.Text>
        </Paragraph>
      </Space>
      
      <Divider />
      
      {/* 数组状态示例 */}
      <Title level={4}>4. 数组状态示例</Title>
      <Space direction="vertical" style={{ width: '100%' }}>
        <Paragraph>
          待办事项列表：
          <ul>
            {todos.map((todo, index) => (
              <li key={index}>{todo}</li>
            ))}
          </ul>
        </Paragraph>
        <Space>
          <Button onClick={() => setTodos([...todos, '新任务'])}>
            添加任务
          </Button>
          <Button onClick={() => setTodos(todos.filter((_, index) => index !== 0))}>
            删除第一个任务
          </Button>
          <Button onClick={() => setTodos([])}>
            清空所有任务
          </Button>
        </Space>
        <Paragraph>
          <Typography.Text type="secondary">
            注意：更新数组状态时，同样需要创建新数组而不是直接修改原数组，
            这符合 React 不可变性原则。
          </Typography.Text>
        </Paragraph>
      </Space>
      
      <Divider />
      
      {/* 复杂状态示例 */}
      <Title level={4}>5. 复杂状态示例（用户列表）</Title>
      <Space direction="vertical" style={{ width: '100%' }}>
        <Paragraph>
          用户列表：
          <ul>
            {users.map(user => (
              <li key={user.id}>
                {user.name} - {user.isActive ? '活跃' : '非活跃'}{' '}
                <Button 
                  size="small" 
                  onClick={() => {
                    setUsers(users.map(u => 
                      u.id === user.id ? {...u, isActive: !u.isActive} : u
                    ));
                  }}
                >
                  切换状态
                </Button>
              </li>
            ))}
          </ul>
        </Paragraph>
        <Button onClick={() => {
          const newUser = {
            id: users.length + 1,
            name: `用户${users.length + 1}`,
            isActive: true
          };
          setUsers([...users, newUser]);
        }}>
          添加新用户
        </Button>
        <Paragraph>
          <Typography.Text type="secondary">
            这个例子展示了如何处理更复杂的嵌套状态更新。
          </Typography.Text>
        </Paragraph>
      </Space>
      
      <Divider />
      
      {/* 函数初始值示例 */}
      <Title level={4}>6. 函数初始值示例</Title>
      <Space direction="vertical" style={{ width: '100%' }}>
        <Paragraph>
          耗时计算结果: <strong>{expensiveValue}</strong>
        </Paragraph>
        <Paragraph>
          <Typography.Text type="secondary">
            这个值是通过耗时计算得到的。使用函数初始值可以避免在每次组件重新渲染时都执行耗时计算。
            可以打开浏览器控制台查看日志，确认计算函数只执行了一次。
          </Typography.Text>
        </Paragraph>
        <Space>
          <Button onClick={() => setExpensiveValue(prev => prev + 1)}>
            增加 (+1)
          </Button>
          <Button onClick={() => setExpensiveValue(prev => prev - 1)}>
            减少 (-1)
          </Button>
        </Space>
      </Space>
      
      <Divider />
      
      <Title level={3}>useState 使用要点</Title>
      <Paragraph>
        <ul>
          <li>
            <strong>状态更新是异步的：</strong>
            调用 setState 后，状态不会立即更新，而是在下一次渲染时生效。
          </li>
          <li>
            <strong>状态更新是替换而不是合并：</strong>
            新状态会完全替换旧状态，而不是合并。
          </li>
          <li>
            <strong>函数式更新：</strong>
            当新状态依赖于前一个状态时，使用函数式更新确保获取到最新状态。
          </li>
          <li>
            <strong>遵循不可变性原则：</strong>
            不要直接修改状态，而是创建新的状态对象或数组。
          </li>
          <li>
            <strong>批量更新：</strong>
            在事件处理函数中，React 会批量处理多次状态更新以提高性能。
          </li>
          <li>
            <strong>函数初始值：</strong>
            当初始状态需要通过复杂计算获得时，可以传递一个函数，该函数只在初始渲染时执行一次。
          </li>
        </ul>
      </Paragraph>
    </Card>
  );
};

export default UseStateTestPage;